﻿create procedure [store].[kvGet]
(
	@Key varchar(255),
	@TTL float null,
	@Version int out,
	@Expiry datetime2 out
) 
as
begin 
	declare @kv table
	(
		[KeyId] bigint not null,
		[Version] int not null
	)

	insert into @kv
	select
		[KeyId],
		[Version]
	from store.[kvPersisted]
	where [Key] = @Key 

	if @@rowcount = 0
	begin
		set @Version = -2147483648
		set @Expiry = null
		return;
	end

	declare @KeyId bigint
	select @KeyId = [KeyId], @Version = [Version] from @kv

	if @TTL is null
	begin
		set @Expiry = null
		select DATALENGTH(Part), Part from store.[kvPersistedValues] where [KeyId] = @KeyId order by [SortOrder]
		return;
	end

	-- If given a TTL, the intent is to rehydrate the in-memory instance:
	set @Expiry = DATEADD(millisecond, @TTL, GETUTCDATE())
	declare @NewKeyId bigint

	insert into mem.kv
	(
		[Key],
		[Version],
		Expiry,
		Harden
	)
	select 
		@Key, 
		[Version], 
		@Expiry, 
		1 
	from @kv;
	set @NewKeyId = SCOPE_IDENTITY();
	
	declare @kvValues table
	(
		[Size] int,
		[Part] varbinary(8000),
		[SortOrder] bigint
	)

	insert into @kvValues select DATALENGTH(Part), Part, [SortOrder] from store.[kvPersistedValues] where [KeyId] = @KeyId 
	insert into mem.kvValues select @NewKeyId, [Part] from @kvValues order by [SortOrder]

	delete from store.kvPersisted where [Key] = @Key
	delete from store.kvPersistedValues where [KeyId] = @KeyId
	select [Size], [Part] from @kvValues order by [SortOrder]
end